package com.ckjw.gobang.view;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import com.ckjw.gobang.connect.Message;
import com.ckjw.gobang.connect.MessageType;
import com.ckjw.gobang.connect.UserClientService;
import com.ckjw.gobang.data.GameCenter;
import com.ckjw.gobang.data.Player;
import com.ckjw.gobang.data.Spot;
import com.ckjw.gobang.data.TableData;
import com.ckjw.gobang.utils.Coordinate;
import com.ckjw.gobang.utils.Path;

/**
 * 界面显示 之 棋桌面板，显示棋盘，绘制棋子 游戏结束的判定： iscanspot putchess gameover gamemode
 * 
 * @author lck and djw
 * @Date 2022年6月6日-下午5:44:15
 */
public class ChessBroad extends JPanel {

	private static final long serialVersionUID = 1L;
	public static ChessBroad myBroad2;
	public static int chessSize;// 不能在这里chessSize = myBroad.getWidth() / 19，因为myboroad没被赋值
	int selectx = -1;
	int selecty = -1;
	// 定义最后下棋的坐标
	public static int lastx = -1;
	public static int lasty = -1;
	// 定义一个BufferedImage，代表当鼠标移动时将要下子的选择框
	private static BufferedImage selected;
	// 先行者黒棋
	public static boolean firstdown = false;

	/**
	 * 构造函数
	 */
	public ChessBroad() {
		this.setVisible(true);
		// 设置鼠标形状为手型
		this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		this.setBackground(new Color(249, 214, 91));
		this.addListener();
		myBroad2 = this;
	}

	/**
	 * 重绘这个面板
	 */
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		// 绘制棋桌
		g.setFont(new Font("黑体", Font.BOLD, 20));
		for (int i = 0; i < 19; i++) {
			// 画每一条行线
			g.drawString("" + (i + 1), 0, 20 + chessSize * i);// 用来显示最左边旁边的数字
			g.drawLine(chessSize / 2 + 10, chessSize / 2 + chessSize * i, chessSize / 2 + chessSize * 18 + 10,
					chessSize / 2 + chessSize * i);// 画连线
			// 列线
			g.drawString("" + (i + 1), chessSize * i + 14, 15);// 行不固定，列固定
			g.drawLine(chessSize / 2 + chessSize * i + 10, chessSize / 2, chessSize / 2 + chessSize * i + 10,
					chessSize / 2 + chessSize * 18);
		}
		// System.out.println("width"+chessSize+"\n");测试
		// 绘制棋子
		for (int i = 0; i < 19; i++) {
			for (int j = 0; j < 19; j++) {
				Spot spot = TableData.getSpot(i, j);
				if (!spot.getColor().equals("none")) {
					int row = spot.getRow() + 1;
					int col = spot.getCol() + 1;
					int cx = Coordinate.colToX(col);
					int cy = Coordinate.rowToY(row);
					String color = spot.getColor();
					// System.out.println("颜色"+color);
					switch (color) {
					case Spot.blackChess:
						g.setColor(Color.black);
						break;
					case Spot.whiteChess:
						g.setColor(Color.white);
						break;
					default:
						break;
					}

					if (!color.equals("none")) {
						g.fillOval(cx - chessSize / 2, cy - chessSize / 2, chessSize, chessSize);// 圆形画法
					}
				}
			}
		}
		// 绘制选中点的红框
		if (selectx > 0 && selecty > 0) {
			g.drawImage(selected, selectx + 12, selecty + 12, null);
		}
		// 绘制最后一个棋子中心点
		if (lastx > 0 && lasty > 0) {
			Graphics2D g2d = (Graphics2D) g;
			g2d.setColor(Color.blue);
			g2d.setStroke(new BasicStroke(5));
			g2d.drawRect(lastx - chessSize / 12, lasty - chessSize / 12, chessSize / 6, chessSize / 6);
		}
		// 检查结束后绘制结束后的连线
		if (TableData.isOver()) {
			Graphics2D g1 = (Graphics2D) g;
			int indexX = Coordinate.colToX(TableData.indexCol + 1);
			int indexY = Coordinate.rowToY(TableData.indexRow + 1);
			int endX = Coordinate.colToX(TableData.endCol + 1);
			int endY = Coordinate.rowToY(TableData.endRow + 1);
			g1.setColor(Color.blue);
			g1.setStroke(new BasicStroke(5.5f));// 采用graphics2d原因就是可以通过stroke加粗
			g1.setFont(new Font("黑体", Font.BOLD, 150));
			g1.drawLine(indexX, indexY, endX, endY);
		}

	}

	/**
	 * 为棋子设置宽度
	 * 
	 * @throws IOException
	 */
	public void init() throws IOException {
		chessSize = myBroad2.getWidth() / 19;
		try {
			selected = ImageIO.read(Path.getsrcurl(this, "images/maininterface/selected.gif"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void addListener() {
		this.addMouseListener(new MouseAdapter() {
			// 鼠标点击
			@Override
			public void mouseClicked(MouseEvent e) {

				// 1.根据鼠标位置创造棋子对象
				int cx = e.getX();
				int cy = e.getY();
				System.out.println("点击坐标" + cx + ":" + cy);
				// 根据坐标，获得行列
				int row = Coordinate.yToRow(cy);
				int col = Coordinate.xToCol(cx);
				Spot spot = new Spot(row - 1, col - 1, TableData.getNowColor());
				System.out.println("点击行列" + row + ":" + col);

				// 2.判断要不要在鼠标点击位置把棋子对象绘制出来
				boolean canSpot = isCanSpot(spot);
				if (canSpot) {
					if (GameCenter.getMode() == GameCenter.MODE_ONLINE) {// 网络对战
						if (firstdown) {// 黒棋用户只能下黒棋
							if (spot.getColor().equals(Spot.blackChess)) {
								UserClientService.startgame(spot, col, row);
							} else {
								JOptionPane.showMessageDialog(MainInterface.mainInterface, "请等待对方下棋", "提示消息",
										JOptionPane.INFORMATION_MESSAGE);
							}
						} else {// 白棋用户只能下白棋
							if (spot.getColor().equals(Spot.whiteChess)) {
								UserClientService.startgame(spot, col, row);
							} else {
								JOptionPane.showMessageDialog(MainInterface.mainInterface, "请等待对方下棋", "提示消息",
										JOptionPane.INFORMATION_MESSAGE);
							}
						}
					} else if (GameCenter.getMode() == GameCenter.MODE_LOCAL) {// 本地对战
						TableData.putDownChess(spot);// 这个函数里面也有判断游戏是否结束。
						// 标记为最后一个棋子
						lastx = Coordinate.colToX(col);
						lasty = Coordinate.rowToY(row);
						myBroad2.repaint();
						// 检查游戏是否结束
						if (TableData.isOver()) {
							aferWin();
						}
					}
				}
			}

			// 当鼠标退出棋盘区域后，复位选中坐标,重绘chessBoard，要保证红色选中框显示正确
			@Override
			public void mouseExited(MouseEvent e) {
				selectx = -1;
				selecty = -1;
				myBroad2.repaint();
			}
		});
		this.addMouseMotionListener(new MouseMotionAdapter() {
			// 鼠标移动
			@Override
			public void mouseMoved(MouseEvent e) {
				int cx = e.getX();
				int cy = e.getY();
				int row = Coordinate.yToRow(cy);
				int col = Coordinate.xToCol(cx);
				selectx = Coordinate.colToX(col - 1);
				selecty = Coordinate.rowToY(row - 1);
				myBroad2.repaint();
			}
		});
	}

	/**
	 * 处理获胜后的情况
	 */
	public static void aferWin() {
		if (GameCenter.getMode()==GameCenter.MODE_LOCAL) {
			// 增加用户积分
			// 当前应该下白棋，则黑棋获胜
			if (!Player.myPlayer.getColor().equals(TableData.getNowColor())) {
				int grade = Player.myPlayer.addGrade(100);
				UserPanel.setGrade(grade, UserPanel.left);

			} else {
				int grade = Player.otherPlayer.addGrade(100);
				UserPanel.setGrade(grade, UserPanel.right);
			}
		}
		GameCenter.setMode(GameCenter.MODE_END);
		ChessBroad.firstdown=false;//重置黑白棋随机
		if (Spot.whiteChess.equals(TableData.getNowColor())) {
			// 当前应该下白棋，则黑棋获胜
			JOptionPane.showMessageDialog(MainInterface.mainInterface, "黑棋获胜!", "游戏结束", JOptionPane.CANCEL_OPTION);
			ControlPanel.my.jtext.append("游戏结果:黑棋获胜！\n");
		} else {
			JOptionPane.showMessageDialog(MainInterface.mainInterface, "白棋获胜!", "游戏结束", JOptionPane.CANCEL_OPTION);
			ControlPanel.my.jtext.append("游戏结果：白棋获胜！\n");
		}

	}

	/**
	 * 判断这个点是否有棋子，和游戏模式是否为未开始模式
	 * 
	 * @param spot
	 * @return
	 */
	public static boolean isCanSpot(Spot spot) {
		if (TableData.hasSpot(spot.getRow(), spot.getCol())) {
			System.out.println("ChessBroad 此点已有棋子！");
			return false;
		}
		if (GameCenter.isEnd()) {
			JOptionPane.showMessageDialog(null, "游戏未开始，或已结束！\n请选择游戏模式，以开始游戏，", "游戏未开始", JOptionPane.CANCEL_OPTION);
			return false;
		}
		return true;
	}

}
